  
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">















 
 
 
 
 
 
 
  
  


<html>
  <head>
    <script type="text/javascript" language="JavaScript">
    ORIGINAL_PAGE_PATH = "/appengine/articles/gae_backup_and_restore.html";
    </script>
    
    
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Using Google App Engine Backup and Restore - Google App Engine - Google Code</title>
<script type="text/javascript"><!--
(function(){function a(){this.t={};this.tick=function(c){this.t[c]=(new Date).getTime()};this.tick("start")}var b=new a;window.jstiming={Timer:a,load:b};if(window.external&&window.external.pageT)window.jstiming.pt=window.external.pageT;})();

var _tocPath_ = '/appengine/docs/_toc.ezt';
var codesite_token = null;
//--></script>
<link href="../../css/codesite.pack.04102009.css" type="text/css" rel="stylesheet"></link>
<script src="../../js/codesite_head.pack.04102009.js" type="text/javascript"></script>
<script type="text/javascript">CODESITE_CSITimer['load'].tick('bhs');</script>
<link rel="search" type="application/opensearchdescription+xml" title="Google Code" href="http://code.google.com/osd.xml" />

<!--[if IE]><link rel="stylesheet" type="text/css" href="../../css/iehacks.css" /><![endif]-->

    <link href="../../css/semantic_headers.css" rel="stylesheet" type="text/css" />
    <link href="../css/local_extensions.css" rel="stylesheet" type="text/css" />
  </head>

  <body class="gc-documentation">

    
    
    
</a>

<div id="gb">
 <span>
  
    <a id="lang-dropdown" class="dropdown" href="http://code.google.com" onclick="return false;"><img class="globeicon" src="../../images/globe2_small.png"/><span>English</span></a>
  
 </span>
</div>

<div class="gbh" style="left: 0pt;"></div>
<div class="gbh" style="right: 0pt;"></div>


<style type="text/css">
  #gc-topnav h1 {
    padding: 0 0 0 6px;
  }
</style>


<div id="gc-container">
<a name="top"></a>
<div id="skipto">
  <a href="#gc-pagecontent-anchor">Skip to page content</a>
  <a href="#gc-toc-anchor">Skip to main navigation</a>
</div>

<div id="gc-header">
  <div id="logo"><a href="http://code.google.com">
  
  
     <img src="../../images/cleardot.gif" height="1px" width="1px" alt="Google Code Home Page" id="gc-logo-img"/>
  
  
  </a></div>
  <div id="search">
    <div id="searchForm" class="searchForm">
      <form id="cse" action="http://www.google.com/cse" accept-charset="utf-8" class="gsc-search-box" onsubmit="executeGSearch(document.getElementById('gsearchInput').value); return false;">
      <noscript>
      <input type="hidden" name="cref" value="http://code.google.com/cse/googlecode-context.xml"/>
      </noscript>
        <table class="gsc-search-box" cellpadding="0" cellspacing="0">
          <tbody>
            <tr>
              <td class="gsc-input">
                <input id="gsearchInput" type="text" name="q" maxlength="2048" class="gsc-input" autocomplete="off" title="Google Code Search" style="width:345px"/>
              </td>
              <td class="gsc-search-button">
                <div id="cs-searchresults" onclick="event.cancelBubble = true;"></div>
                <input title="Search" id="gsearchButton" class="gsc-search-button" name="sa" value="Search" type="submit"/>
              </td>
            </tr>
            <tr>
              <td colspan="2" class="greytext">e.g. "templates" or "datastore"</td>
            </tr>
          </tbody>
        </table>
      </form>
    </div> <!-- end searchForm -->
  </div> <!-- end search -->
</div> <!-- end gc-header -->


<div id="codesiteContent">

<a name="gc-topnav-anchor"></a>
<div id="gc-topnav">
  <h1>Google App Engine</h1>
  <ul id="articles" class="gc-topnav-tabs">

    <li id="home_link">
      <a href="../index.html" title="Google App Engine home page">Home</a>
    </li>
  
    <li id="docs_link">
      <a href="../docs/index.html" title="Official Google App Engine documentation">Docs</a>
    </li>
  
    <li id="faq_link">
      <a href="../kb/index.html" title="Answers to frequently asked questions about Google App Engine">FAQ</a>
    </li>
  
    <li id="articles_link">
      <a href="index.html" class="selected" title="Focused articles and tutorials for Google App Engine developers">Articles</a>
    </li>
  
    <li>
      <a href="http://googleappengine.blogspot.com/" title="Official Google App Engine blog">Blog</a>
    </li>
  
    <li>
      <a href="../community.html" title="Community home for Google App Engine">Community</a>
    </li>
  
    <li>
      <a href="../terms.html" title="Google App Engine terms of service">Terms</a>
    </li>
  
    <li>
      <a href="../downloads.html" title="Download Google App Engine">Download</a>
    </li>
  

  </ul>
</div> <!-- end gc-topnav -->

    <div class="g-section g-tpl-170">

      <a name="gc-toc-anchor"></a>  
      <div class="g-unit g-first" id="gc-toc">
        <ul>
  <li><a href="../downloads.html">Downloads</a></li>
  <li><a href="http://code.google.com/status/appengine">System Status</a></li>
  <li><a href="http://code.google.com/p/googleappengine/issues/list">Issue Tracker</a></li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Getting Started</h2>
    <ul>
      <li><a href="../docs/whatisgoogleappengine.html">What Is Google App Engine?</a></li>
      <li><a href="../docs/java/gettingstarted/index.html">Java</a>
        <ul>
              <li><a href="../docs/java/gettingstarted/introduction.html">Introduction</a></li>
    <li><a href="../docs/java/gettingstarted/installing.html">Installing the Java SDK</a></li>
    <li><a href="../docs/java/gettingstarted/creating.html">Creating a Project</a></li>
    <li><a href="../docs/java/gettingstarted/usingusers.html">Using the Users Service</a></li>
    <li><a href="../docs/java/gettingstarted/usingjsps.html">Using JSPs</a></li>
    <li><a href="../docs/java/gettingstarted/usingdatastore.html">Using the Datastore with JDO</a></li>
    <li><a href="../docs/java/gettingstarted/staticfiles.html">Using Static Files</a></li>
    <li><a href="../docs/java/gettingstarted/uploading.html">Uploading Your Application</a></li>

        </ul>
      </li>
      <li><a href="../docs/python/gettingstarted/index.html">Python</a>
        <ul>
            <li><a href="../docs/python/gettingstarted/introduction.html">Introduction</a></li>
  <li><a href="../docs/python/gettingstarted/devenvironment.html">The Development Environment</a></li>
  <li><a href="../docs/python/gettingstarted/helloworld.html">Hello, World!</a></li>
  <li><a href="../docs/python/gettingstarted/usingwebapp.html">Using the webapp Framework</a></li>
  <li><a href="../docs/python/gettingstarted/usingusers.html">Using the Users Service</a></li>
  <li><a href="../docs/python/gettingstarted/handlingforms.html">Handling Forms With webapp</a></li>
  <li><a href="../docs/python/gettingstarted/usingdatastore.html">Using the Datastore</a></li>
  <li><a href="../docs/python/gettingstarted/templates.html">Using Templates</a></li>
  <li><a href="../docs/python/gettingstarted/staticfiles.html">Using Static Files</a></li>
  <li><a href="../docs/python/gettingstarted/uploading.html">Uploading Your Application</a></li>

        </ul>
      </li>
    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Java <sup class="new">Early Look</sup></h2>
    <ul>
          <li><a href="../docs/java/overview.html">Overview</a></li>
    <li><a href="../docs/java/runtime.html">Servlet Environment</a></li>
    <li><a href="../docs/java/datastore/index.html">Storing Data</a>
      <ul>
            <li><a href="../docs/java/datastore/overview.html">Overview</a></li>
    <li><a href="../docs/java/datastore/usingjdo.html">Using JDO</a></li>
    <li><a href="../docs/java/datastore/dataclasses.html">Defining Data Classes</a></li>
    <li><a href="../docs/java/datastore/creatinggettinganddeletingdata.html">Creating, Getting and Deleting Data</a></li>
    <li><a href="../docs/java/datastore/queriesandindexes.html">Queries and Indexes</a></li>
    <li><a href="../docs/java/datastore/transactions.html">Transactions</a></li>
    <li><a href="../docs/java/datastore/relationships.html">Relationships</a></li>
    <li><a href="../docs/java/datastore/usingjpa.html">Using JPA</a></li>
    <li><a href="../docs/java/javadoc/com/google/appengine/api/datastore/package-summary.html">Low-level API</a></li>

      </ul>
    </li>
    <li><a href="../docs/java/apis.html">Services</a>
      <ul>
        <li><a href="../docs/java/memcache/index.html">Memcache</a>
          <ul>
                <li><a href="../docs/java/memcache/overview.html">Overview</a></li>
    <li><a href="../docs/java/memcache/usingjcache.html">Using JCache</a></li>
    <li><a href="../docs/java/javadoc/com/google/appengine/api/memcache/package-summary.html">Low-level API</a></li>

          </ul>
        </li>
        <li><a href="../docs/java/urlfetch/index.html">URL Fetch</a>
          <ul>
                <li><a href="../docs/java/urlfetch/overview.html">Overview</a></li>
    <li><a href="../docs/java/urlfetch/usingjavanet.html">Using java.net</a></li>
    <li><a href="../docs/java/javadoc/com/google/appengine/api/urlfetch/package-summary.html">Low-level API</a></li>

          </ul>
        </li>
        <li><a href="../docs/java/mail/index.html">Mail</a>
          <ul>
                <li><a href="../docs/java/mail/overview.html">Overview</a></li>
    <li><a href="../docs/java/mail/usingjavamail.html">Using JavaMail</a></li>
    <li><a href="../docs/java/javadoc/com/google/appengine/api/mail/package-summary.html">Low-level API</a></li>

          </ul>
        </li>
        <li><a href="../docs/java/images/index.html">Images</a>
          <ul>
                <li><a href="../docs/java/images/overview.html">Overview</a></li>
    <li><a href="../docs/java/javadoc/com/google/appengine/api/images/package-summary.html">API Reference</a></li>

          </ul>
        </li>
        <li><a href="../docs/java/users/index.html">Google Accounts</a>
          <ul>
                <li><a href="../docs/java/users/overview.html">Overview</a></li>
    <li><a href="../docs/java/javadoc/com/google/appengine/api/users/package-summary.html">API Reference</a></li>

          </ul>
        </li>
      </ul>
    </li>
    <li><a href="../docs/java/javadoc/index.html">Javadoc Reference</a></li>
    <li><a href="../docs/java/jrewhitelist.html">JRE Class White List</a></li>
    <li><a href="../docs/java/config/index.html">Configuration</a>
      <ul>
            <li><a href="../docs/java/config/webxml.html">Deployment Descriptor</a></li>
    <li><a href="../docs/java/config/appconfig.html">App Config</a></li>
    <li><a href="../docs/java/config/indexconfig.html">Index Config</a></li>
    <li><a href="../docs/java/config/cron.html">Scheduled Tasks</a></li>

      </ul>
    </li>
    <li><a href="../docs/java/tools/index.html">Tools</a>
      <ul>
            <li><a href="../docs/java/tools/devserver.html">Development Server</a></li>
    <li><a href="../docs/java/tools/uploadinganapp.html">Uploading and Managing</a></li>
    <li><a href="../docs/java/tools/eclipse.html">Google Plugin for Eclipse</a></li>
    <li><a href="../docs/java/tools/ant.html">Using Apache Ant</a></li>

      </ul>
    </li>
    <li><a href="../docs/java/howto/index.html">How-To</a>
      <ul>
              <li><a href="../docs/java/howto/unittesting.html">Unit Testing</a></li>

      </ul>
    </li>

    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Python</h2>
    <ul>
          <li><a href="../docs/python/overview.html">Overview</a></li>
    <li><a href="../docs/python/runtime.html">CGI Environment</a></li>
    <li><a href="../docs/python/datastore/index.html">Storing Data</a>
      <ul>
             <li><a href="../docs/python/datastore/overview.html">Overview</a></li>
     <li><a href="../docs/python/datastore/entitiesandmodels.html">Entities and Models</a></li>
     <li><a href="../docs/python/datastore/creatinggettinganddeletingdata.html">Creating, Getting and Deleting Data</a></li>
     <li><a href="../docs/python/datastore/keysandentitygroups.html">Keys and Entity Groups</a></li>
     <li><a href="../docs/python/datastore/queriesandindexes.html">Queries and Indexes</a></li>
     <li><a href="../docs/python/datastore/transactions.html">Transactions</a></li>
     <li><a href="../docs/python/datastore/typesandpropertyclasses.html">Types and Property Classes</a></li>
     <li><a href="../docs/python/datastore/gqlreference.html">GQL Reference</a></li>

     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../docs/python/datastore/modelclass.html">Model</a></li>
         <li><a href="../docs/python/datastore/expandoclass.html">Expando</a></li>
         <li><a href="../docs/python/datastore/polymodelclass.html">PolyModel</a></li>
         <li><a href="../docs/python/datastore/propertyclass.html">Property</a></li>
         <li><a href="../docs/python/datastore/queryclass.html">Query</a></li>
         <li><a href="../docs/python/datastore/gqlqueryclass.html">GqlQuery</a></li>
         <li><a href="../docs/python/datastore/keyclass.html">Key</a></li>
         <li><a href="../docs/python/datastore/functions.html">Functions</a></li>
         <li><a href="../docs/python/datastore/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

      </ul>
    </li>
    <li><a href="../docs/python/apis.html">Services</a>
      <ul>
        <li><a href="../docs/python/memcache/index.html">Memcache</a>
          <ul>
                 <li><a href="../docs/python/memcache/overview.html">Overview</a></li>
      <li><a href="../docs/python/memcache/usingmemcache.html">Using Memcache</a></li>
     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../docs/python/memcache/clientclass.html">Client</a></li>
         <li><a href="../docs/python/memcache/functions.html">Functions</a></li>
       </ul>
     </li>

          </ul>
        </li>
        <li><a href="../docs/python/urlfetch/index.html">URL Fetch</a>
          <ul>
                 <li><a href="../docs/python/urlfetch/overview.html">Overview</a></li>
     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../docs/python/urlfetch/fetchfunction.html">The fetch Function</a></li>
         <li><a href="../docs/python/urlfetch/responseobjects.html">Response Objects</a></li>
         <li><a href="../docs/python/urlfetch/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

          </ul>
        </li>
        <li><a href="../docs/python/mail/index.html">Mail</a>
          <ul>
                 <li><a href="../docs/python/mail/overview.html">Overview</a></li>
     <li><a href="../docs/python/mail/sendingmail.html">Sending Mail</a></li>
     <li><a href="../docs/python/mail/attachments.html">Attachments</a></li>
     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../docs/python/mail/emailmessageclass.html">EmailMessage</a></li>
         <li><a href="../docs/python/mail/emailmessagefields.html">Message Fields</a></li>
         <li><a href="../docs/python/mail/functions.html">Functions</a></li>
         <li><a href="../docs/python/mail/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

          </ul>
        </li>
        <li><a href="../docs/python/images/index.html">Images</a>
          <ul>
                 <li><a href="../docs/python/images/overview.html">Overview</a></li>
     <li><a href="../docs/python/images/installingPIL.html">Installing PIL</a></li>
     <li><a href="../docs/python/images/usingimages.html">Using the Images API</a></li>
     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../docs/python/images/imageclass.html">Image</a></li>
         <li><a href="../docs/python/images/functions.html">Functions</a></li>
         <li><a href="../docs/python/images/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

          </ul>
        </li>
        <li><a href="../docs/python/users/index.html">Google Accounts</a>
          <ul>
                 <li><a href="../docs/python/users/overview.html">Overview</a></li>
     <li><a href="../docs/python/users/userobjects.html">User Objects</a></li>
     <li><a href="../docs/python/users/loginurls.html">Login URLs</a></li>
     <li><a href="../docs/python/users/adminusers.html">Admin Users</a></li>

     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../docs/python/users/userclass.html">User</a></li>
         <li><a href="../docs/python/users/functions.html">Functions</a></li>
         <li><a href="../docs/python/users/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

          </ul>
        </li>
      </ul>
    </li>
    <li><a href="../docs/python/config/index.html">Configuration</a>
      <ul>
            <li><a href="../docs/python/config/appconfig.html">App Config</a></li>
    <li><a href="../docs/python/config/indexconfig.html">Index Config</a></li>
    <li><a href="../docs/python/config/cron.html">Scheduled Tasks</a></li>

      </ul>
    </li>
    <li><a href="../docs/python/tools/index.html">Tools</a>
      <ul>
            <li><a href="../docs/python/tools/devserver.html">Development Server</a></li>
    <li><a href="../docs/python/tools/uploadinganapp.html">Uploading and Managing</a></li>
    <li><a href="../docs/python/tools/uploadingdata.html">Uploading Data</a></li>
    <li><a href="../docs/python/tools/webapp/index.html">webapp Framework</a>
      <ul>
             <li><a href="../docs/python/tools/webapp/overview.html">Overview</a></li>
     <li><a href="../docs/python/tools/webapp/running.html">Running the Application</a></li>
     <li><a href="../docs/python/tools/webapp/requesthandlers.html">Request Handlers</a></li>
     <li><a href="../docs/python/tools/webapp/requestdata.html">Request Data</a></li>
     <li><a href="../docs/python/tools/webapp/buildingtheresponse.html">Building the Response</a></li>
     <li><a href="../docs/python/tools/webapp/redirects.html">Redirects, Headers and Status Codes</a></li>
     

     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../docs/python/tools/webapp/requestclass.html">Request</a></li>
         <li><a href="../docs/python/tools/webapp/responseclass.html">Response</a></li>
         <li><a href="../docs/python/tools/webapp/requesthandlerclass.html">RequestHandler</a></li>
         <li><a href="../docs/python/tools/webapp/wsgiapplicationclass.html">WSGIApplication</a></li>
         <li><a href="../docs/python/tools/webapp/utilmodule.html">Utility Functions</a></li>
         
       </ul>
     </li>

      </ul>
    </li>
    <li><a href="../docs/python/tools/libraries.html">Third-party Libraries</a></li>

      </ul>
    </li>
    <li><a href="../docs/python/howto/index.html">How-To</a>
      <ul>
              <li><a href="../docs/python/howto/usinggdataservices.html">Google Data Services</a></li>

      </ul>
    </li>

    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Managing Your App</h2>
    <ul>
      <li><a href="../docs/theadminconsole.html">The Admin Console</a></li>
      <li><a href="../docs/quotas.html">Quotas</a></li>
      <li><a href="../docs/billing.html">Billing</a></li>
    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Resources</h2>
    <ul>
      <li><a href="../kb/index.html">FAQ</a></li>
      <li><a href="index.html">Articles</a></li>
      <li><a href="http://appengine-cookbook.appspot.com/">Cookbook</a></li>
      <li><a href="http://appgallery.appspot.com/">App Gallery</a></li>
      <li><a href="http://code.google.com/p/googleappengine/">SDK Code</a></li>
      <li><a href="http://code.google.com/p/google-app-engine-samples/">Sample Apps Code</a></li>
      <li><a href="../community.html">Discussion Groups</a></li>
    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><a href="../docs/roadmap.html">Product Roadmap</a></li>
  <li><a href="http://code.google.com/p/googleappengine/wiki/SdkReleaseNotes">Release Notes</a></li>
  <li><a href="../docs/revision_history.html">Revision History</a></li>
</ul>

        <a class="hidden" href="#gc-topnav-anchor">More Google App Engine resource links</a>
      </div>
      
      <a name="gc-pagecontent-anchor"></a>   
      <div class="g-unit" id="gc-pagecontent">
        <script type="text/javascript">CODESITE_docEarlyProcessing();</script>
        <h1 class="page_title">Using Google App Engine Backup and Restore</h1>


<div id="jd-content">
<div class="jd-descr">
<p class="note">
This article was written and submitted by an external contributor.
The Google App Engine team thanks Aral Balkan for his time and expertise.
</p>
<i>Aral Balkan</i><br>
<i>January 23, 2009</i>

<h2>Introduction</h2>

<p>When I started developing the web site for the <a href="http://www.headconference.com/">&lt;head&gt; web conference</a> on Google App Engine towards the end of last year, it dawned on me pretty quickly that one of my main development challenges would be to find a way to export all of the data we would be collecting in case something went wrong with the deployment datastore. The difference between having a backup and not was the difference between braving a few hours of down-time and canceling the conference because we had lost all of our registration data. Since Google App Engine does not come with a data backup solution (Google is currently working on its own datastore import and export utility for large datasets which is currently on the roadmap for the first quarter of 2009), it was up to me to build my own.</p>

<p>This is what prompted me to write <a href="http://aralbalkan.com/1784">Google App Engine Backup and Restore</a> (or <a href="http://aralbalkan.com/1784">Gaebar</a>, for short).</p>

<p>While designing Gaebar, I knew that having backups alone would not be enough if there wasn't an easy way to restore those backups. The real value of a backup, after all, is in the restore.</p>

<h2>How it works</h2>

<p>Backing up an entire datastore is not a trivial task on Google App Engine since App Engine currently has just one <em>modus operandi</em>. App Engine supports a massively-scalable model based on requests and responses where each response must return within ten seconds. It doesn't currently have a mode of operation that isn't required to scale but which supports long-running processes. The current workaround is to fake long-running processes by using a client-side engine and breaking up batch operations into bite-sized portions that work within the massively-scalable request-response model. Building administrative features in this way is somewhat akin to using a Ferrari to go from your bedroom to the bathroom: it's overkill and quite uncomfortable but can be made to work if you want it badly enough. This is the method that Gaebar uses to enable easy backups and restores on the Google App Engine platform.</p>

<p>Gaebar backs up your datastore, a few rows at a time, into Python functions and stores these functions in python modules called code shards that are less than 1MB in size each. To restore your datastore, Gaebar runs these functions, in successive requests, to recreate the models and entities in your datastore.</p>

<p>In other words, Gaebar backs up your datastore to Python code and then runs that code to restore it. And, it does all this while staying within the 10 second execution limit and the 1MB size limit on data structures that are currently in effect on the deployment environment.</p>

<p>Gaebar automates the backup and restore process as much as possible, going so far as to automatically download your backups from the deployment environment onto your local development server.</p>

<p>And you control the whole process via an easy-to-use, if pink, online interface.</p>

<h2>Back me up, Scotty!</h2>

<p>First off, understand that Gaebar only works with Django projects. So, if you're using webapp, I'm sorry to say that you're currently out of luck. (If you happen to port Gaebar to webapp, please do let me know.)</p>

<h3>First things first, a patch</h3>

<p>Before you can run Gaebar, you must patch your <code>dev_appserver.py</code> as per the instructions here: <a href="http://aralbalkan.com/1440">http://aralbalkan.com/1440</a> (and please star issue <a href="http://code.google.com/p/googleappengine/issues/detail?id=616">616</a> if you'd like Google to fix this so we can remove this step).

<p>This is required in order to override some of the local development server restrictions to allow the automatic download of backups. Gaebar will not work unless you implement this patch.</p>

<h3>Quick start: Running the test suites</h3>

<p>The easiest way to get started with Gaebar is to download one of the two test suite applications, <a href="http://github.com/aral/gaebar-gaed/tree/master">Gaebar Gead</a> or <a href="http://github.com/aral/gaebar-gaed/tree/master">Gaebar App-Engine-Patch</a>.</p>

<p>The test suite applications are built on the <a href="http://code.google.com/p/google-app-engine-django/">Google App Engine Helper</a> and <a href="http://code.google.com/p/app-engine-patch/">app-engine-patch</a> skeletons, respectively, and come pre-configured with Gaebar. You can simply download one of the test apps and follow the instructions to populate a test datastore, run a backup/restore, and run the test suite to make sure that everything is working.</p>

<h3>Starting a new Django application</h3>

<p>For your own projects, the easiest way to get started with Gaebar is if you're building a new Django application. You can simply download the <a href="http://github.com/aral/gaebar-gaed-skeleton/tree/master">Gaebar Gaed Skeleton</a> which contains a base Google App Engine Django install, including a zipped up Django 1.x and Gaebar.</p>

<h3>Adding Gaebar to an existing Django project</h3>

<p>If you already have a Django project, you need to add the Gaebar app to it. (Gaebar is just a regular Django app). An overview of how to do this is provided below but you should really read the <code>readme.txt</code> file that comes with Gaebar for full step-by-step instructions.</p>

<p>Start by downloading the Gaebar. You can <a href="http://github.com/aral/gaebar/tree/master">download Gaebar Beta 3 as a zip from GitHub</a> or, if you're a Gitball Wizard, you can use Git to add the Gaebar master branch to your project as a submodule.</p>

<p>Once you have downloaded Gaebar, install it into your Django project by following this general overview:</p>

<ol>
  <li>Modify <code>urls.py</code> to add the URL mappings for Gaebar </li>
  <li>Add the URL mapping for the Gaebar static assets folder to <code>app.yaml</code></li>
  <li>Add the index used by Gaebar to your <code>index.yaml</code></li>
  <li>Modify your <code>settings.py</code> to add the Gaebar settings that specify, among others, the location of your local development server and the models that you want to back up.</li>
</ol>

<p>(Again, for step-by-step instructions, see the <code>readme.txt</code> file that comes with Gaebar.)</p>

<p>Once you've installed Gaebar, you can test that everything is working by firing up your local development server and accessing Gaebar at the <code>/gaebar</code> URL. (e.g., <a href="http://localhost:8000/gaebar">http://localhost:8000/gaebar</a>). You should see the Gaebar interface. </p>

<h2>Backup...</h2>

<p>Since backing up your local datastore isn't terribly exciting, you will most likely want to deploy your application to the deployment environment (e.g., <a href="http://example.com/">http://myawesomeapp.appspot.com</a>) and start your first backup.</p>

<p class="note"><strong>Important</strong>: Make sure that your local development server is running <em>before</em> you start a backup as Gaebar will automatically hit your local server to download your remote backup to your local machine.</p>

<p>Once your backup is complete, you can find it in the <code>/gaebar/backups/</code> folder. Go ahead and take a look at what it contains. It's just lots of pickled Python code. </p>

<p>Once you have a backup, you have several options for where you can restore it, based on the use cases below.</p>

<h2>... and restore!</h2>

<h3>Use case: develop and test locally with real data</h3>

<p><strong>Restore to</strong>: your local development server.</p>

<p>Once you have restored the data to your local development server, I would highly suggest that you take a backup of your datastore.</p>

<p>You can find your datastore files in a temporary folder on your local machine (e.g., on my Mac, it's <code>/var/folders/bz/bzDU030xHXK-jKYLMXnTzk+++TI/-Tmp-/</code>). To find the folder on your own machine, flush the datastore (<code>./manage.py flush</code>) and you will see the path to your datastore folder printed in the resulting output.</p>

<p>Once you know the path of the temporary folder that holds your datastore, copy the <code>django_my_project_name_.datastore</code> and <code>django_my_project_name_.datastore.history</code> files somewhere safe. Then, if you ever need to restore the datastore again, you can simply copy those files back into the temporary folder instead of having to go through the whole restore process again. This will save you a lot of time especially when working with large datastores.</p>

<h3>Use case: disaster recovery</h3>

<p><strong>Restore to</strong>: the same application instance that you backed up from on the deployment environment.</p>

<p>In the unlikely event that disaster strikes and the datastore for your live application becomes either corrupted or lost, you can restore your datastore from your backup.</p>

<p>I would only recommend doing this if something has really gone terribly wrong on your live application and you absolutely need to revert to a backed up version of the datastore. This would be a good time to mention that Gaebar does not come with any warranties (go ahead, read the license, I'll wait around till you're done) and that restoring is a <em>destructive</em> process. If, for any reason, your restore fails, and data is corrupted or lost due to a bug in your code, you will not be able to revert your datastore to its previous state or recover your data. Developer beware!</p>

<h3>Use case: create a staging application</h3>

<p><strong>Restore to</strong>: a different application instance on the deployment environment.</p>

<p>Now here's where it gets interesting! You're not limited to restoring your backup to the same instance of your application that you backed up from. Simply change the app name in your <code>app.yaml</code>, deploy, and run the restore to restore your backup to a different application instance.</p>

<p>What this means is that you can now have a staging application, running on the same deployment environment as your live application, that you can test with using live data. (You use the staging application in much the same way as you would use a staging server in traditional web development.)</p>

<p>Regardless of whether you decide to use a staging application in your workflow, I would highly recommend that you do a restore to a different application instance after you've backed up your live datastore for the first time to make sure that the backup restores successfully. A bad time to realize that it doesn't would be when you have to perform disaster recovery on your live application instance.</p>

<h2>In conclusion</h2>

<p>Google App Engine is an exciting new cloud platform with the potential to revolutionize how we build and deploy web applications. You must remember, however, that it is currently a pre-release product and is under continuous development. As such, it is understandable that it may currently lack certain features. One such feature that has, until recently, been missing is a simple means to back up the data in your application's datastore. Gaebar is a recently-released, open source, third-party Django application that fills this gap and brings and easy datastore back up and restore solution to Google App Engine.</p>

<p>So, what are you waiting for? <a href="http://github.com/aral/gaebar/tree/master">Back up your datastore already</a> and start sleeping better at night!</p>

<hr/>

<p><strong>Downloads:</strong> The current version of Gaebar, as of this writing is <a href="http://github.com/aral/gaebar/tree/0.3">Beta 3</a>. You can find the latest version on the <a href="http://github.com/aral/gaebar/tree/master">master branch of the Gaebar GitHub repository</a>.</p>

<hr/>

<h3>About the Author...</h3>

<div style="float: left; padding-bottom: 5px; padding-right: 5px;">
<img src="img/aral.png" alt="Aral Balkan" style="border: 1px solid black;" width="55"></a>
</div>

<p>Aral is a developer, professional speaker, consultant, author, and entrepreneur. Last year, his company Naklab staged a fully-virtual web conference called <a href="http://www.headconference.com/">&lt;head&gt;</a>, using Flash Platform technologies alongside App Engine. Aral blogs at <a href="http://aralbalkan.com/">aralbalkan.com</a> and you can tweet to him <a href="http://twitter.com/aral">@aral</a>.</p>

</div>
</div>
   
      </div><!-- end gc-pagecontent -->
   </div><!-- end gooey wrapper -->

    </div> <!-- end codesite content -->

<div id="gc-footer" dir="ltr">
  <div class="text">
    
      <div class="notice"><div id="notice" style="text-align: center; border: 1em 0em 1em 0em">
  Except as otherwise <a
  href="http://code.google.com/policies.html#restrictions">noted</a>,
  the content of this page is licensed under the <a rel="license"
  href="http://creativecommons.org/licenses/by/2.5/">Creative Commons
  Attribution 2.5 License</a>, and code samples are licensed under the
  <a rel="license" href="http://www.apache.org/licenses/LICENSE-2.0">Apache
  2.0 License</a>.
<!-- <rdf:RDF xmlns="http://web.resource.org/cc/" 
              xmlns:dc="http://purl.org/dc/elements/1.1/"
              xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <Work rdf:about="">
    <license rdf:resource="http://creativecommons.org/licenses/by/2.5/" />
  </Work>
  <License rdf:about="http://creativecommons.org/licenses/by/2.5/">
    <permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
    <permits rdf:resource="http://web.resource.org/cc/Distribution"/>
    <requires rdf:resource="http://web.resource.org/cc/Notice"/>
    <requires rdf:resource="http://web.resource.org/cc/Attribution"/>
    <permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
  </License>
</rdf:RDF> -->
</div>
Java is a registered trademark of Sun Microsystems, Inc.</div>
    
    &copy;2009 Google -
    <a href="http://code.google.com">Code Home</a> -
    <a href="http://www.google.com/accounts/TOS">Terms of Service</a> -
    <a href="http://www.google.com/privacy.html">Privacy Policy</a> -
    <a href="http://code.google.com/more">Site Directory</a>
    <br /> <br />
    Google Code offered in:
    <a href="http://code.google.com/intl/en">English</a> -
    <a href="http://code.google.com/intl/es">Español</a> -
    <a href="http://code.google.com/intl/ja">日本語</a> -
    <a href="http://code.google.com/intl/ko">한국어</a> -
    <a href="http://code.google.com/intl/pt-BR">Português</a> -
    <a href="http://code.google.com/intl/ru">Pусский</a> -
    <a href="http://code.google.com/intl/zh-CN">中文(简体)</a> -
    <a href="http://code.google.com/intl/zh-TW">中文(繁體)</a>
  </div>
</div><!-- end gc-footer -->

</div><!-- end gc-containter -->

<script type="text/javascript">CODESITE_CSITimer['load'].tick('ats');</script>
<script src="../../js/codesite_tail.pack.04102009.js" type="text/javascript"></script>






  </body>
</html>


